package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;

import control.networking.RiskClient;

import model.Card;
import model.Combat;
import model.Continent;
import model.LastAction;
import model.LastActionEnum;
import model.Map;
import model.NullPlayer;
import model.Player;
import model.Territory;
import model.AI.MapInfo;
import model.Map.GamePhase;
import model.Player.PlayerTurn;

public class RiskPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Map gameMap;
	private Map oldMap;
	private Player player;
	private Player.PlayerTurn turn;
	private UUID playerID;
	private Territory territoryOne;
	private Territory territoryTwo;
	private ArrayList<TerritoryLabel> labels;
	private JPanel gridLeftPlayers;
	private JPanel gridRightPlayers;
	private JPanel actionPanel;
	private JPanel newGameButtons;
	private JPanel bonusButtons;
	private JPanel cardButtons;
	private JPanel attackButtons;
	private JPanel fortifyButtons;
	private JPanel waitingButtons;
	private JLabel map;
	private JLabel topPanel;
	private JLabel territory1;
	private JLabel territory2;
	private JPanel t1Panel;
	private JPanel t2Panel;
	private BufferedImage mapImageG;
	private BufferedImage mapColoredImage;
	private BufferedImage alphaMap;
	/**
	 * Creates the RiskPanel that shows a graphical representation of the Game
	 * @param gamemap
	 * @param thisPlayer
	 */
	public RiskPanel(Map gamemap, Player thisPlayer) {
		this.gameMap = gamemap;
		player = thisPlayer;
		System.out.println("RP player turnphase at start = "
				+ player.getTurnPhase());
		playerID = player.getUUID();

		this.setLayout(new BorderLayout());

		// set background image (ColoredMap)
		try {
			mapColoredImage = ImageIO
					.read(new File("images/ColorCodedMap.png"));
		} catch (IOException e) {

		}
		try {
			mapImageG = ImageIO.read(new File("images/RiskMapColored.png"));
		} catch (IOException e) {

		}
		try {
			alphaMap = ImageIO.read(new File("images/AlphaMapImage.png"));
		} catch (IOException e) {

		}

		topPanel = new JLabel("Welcome To CSC 335 RISK!");
		topPanel.setHorizontalTextPosition(SwingConstants.CENTER);
		this.add(topPanel, BorderLayout.NORTH);

		map = new JLabel();
		// map.setIcon(mapImage);
		map.addMouseListener(new MouseClickEvent(mapColoredImage));
		// map.setMaximumSize(new Dimension(725,390));
		// map.setMinimumSize(new Dimension(725,380));
		// map.setBorder(new LineBorder(new Color(100), 3));
		this.add(map, BorderLayout.CENTER);

		gridLeftPlayers = new JPanel();
		gridRightPlayers = new JPanel();

		actionPanel = new JPanel();

		newGameButtons = new JPanel();
		newGameButtons.setLayout(new FlowLayout());

		bonusButtons = new JPanel();
		bonusButtons.setLayout(new FlowLayout());

		cardButtons = new JPanel();
		cardButtons.setLayout(new FlowLayout());

		attackButtons = new JPanel();
		attackButtons.setLayout(new FlowLayout());

		fortifyButtons = new JPanel();
		fortifyButtons.setLayout(new FlowLayout());

		waitingButtons = new JPanel();
		waitingButtons.setLayout(new FlowLayout());

		JButton addOne = new JButton("Add One to T1");
		addOne.addActionListener(new AddOneListener());
		JLabel addOneLabel = new JLabel(
				"Select Your Territory To Place One Army");
		//JButton endAddOne = new JButton("End Add One Turn");
		//endAddOne.addActionListener(new EndAddOneListener());

		JButton addTroopsButton = new JButton("Add Troops to T1");
		addTroopsButton.addActionListener(new AddTroopsListener());
		JLabel startCaption = new JLabel("Place Your Bonus Troops");
		JButton endAddButton = new JButton("Done Adding Troops");
		endAddButton.addActionListener(new EndAddListener());

		JButton tradeCardsButton = new JButton("Trade Cards");
		tradeCardsButton.addActionListener(new TradeCardsListener());
		JLabel tradeLabel = new JLabel(" Trade Your Cards ");
		JButton endTradeButton = new JButton("Done Trading");
		endTradeButton.addActionListener(new EndTradeListener());

		JButton startAttackButton = new JButton("T1_Attack_T2");
		startAttackButton.addActionListener(new startAttackListener());
		JButton endAttackButton = new JButton("End Attack");
		endAttackButton.addActionListener(new endAttackListener());
		JLabel attackCaption = new JLabel(
				"Select a Territory to Attack or click End Attack");

		JButton fortifyButton = new JButton("Fortify from T1 to T2");
		fortifyButton.addActionListener(new FortifyListener());
		JButton endTurnButton = new JButton("End Turn");
		endTurnButton.addActionListener(new EndTurnListener());
		JLabel fortifyCaption = new JLabel(
				"Select Territories to Move Troops From or End Turn");

		JLabel waitingLabel = new JLabel(" NOT MY TURN ");

		newGameButtons.add(addOne);
		newGameButtons.add(addOneLabel);
		// newGameButtons.add(endAddOne);

		bonusButtons.add(addTroopsButton);
		bonusButtons.add(startCaption);
		bonusButtons.add(endAddButton);

		cardButtons.add(tradeCardsButton);
		cardButtons.add(tradeLabel);
		cardButtons.add(endTradeButton);

		attackButtons.add(startAttackButton);
		attackButtons.add(attackCaption);
		attackButtons.add(endAttackButton);

		fortifyButtons.add(fortifyButton);
		fortifyButtons.add(fortifyCaption);
		fortifyButtons.add(endTurnButton);

		waitingButtons.add(waitingLabel);

		territory1 = new JLabel("Territory 1: No Territory Selected");
		territory2 = new JLabel("Territory 2: No Territory Selected");
		territory1.setBorder(new LineBorder(Color.BLACK, 2));
		territory2.setBorder(new LineBorder(Color.BLACK, 2));
		t1Panel = new JPanel();
		t2Panel = new JPanel();
		t1Panel.add(territory1);
		t1Panel.setBackground(Color.WHITE);
		t2Panel.add(territory2);
		t2Panel.setBackground(Color.WHITE);

		// actionPanel.add(territory1);
		// actionPanel.add(newGameButtons);
		// actionPanel.add(territory2);

		// this.add(actionPanel, BorderLayout.SOUTH);

		Iterator<Continent> it = gameMap.getContinentList().iterator();//MapInfo.
		// listTerritories
		// ().
		// iterator
		// ();

		labels = new ArrayList<TerritoryLabel>();
		while (it.hasNext()) {
			Iterator<Territory> it2 = it.next().listTerritory().iterator();
			while (it2.hasNext()) {
				TerritoryLabel temp = new TerritoryLabel(it2.next());
				labels.add(temp);
				temp.paintLabel();
			}
		}
		setPlayers();

		// Graphics2D g = mapImageG.createGraphics();
		// g.drawImage(alphaMap, 0, 0, null );
		// map.setIcon(new ImageIcon(mapImageG));

		updateMap(gameMap);

		// // populate territories for testing
		// for (int i = 0; i < labels.size(); i++) {
		// labels.get(i).getTerritory().addTroop(i);
		// labels.get(i).paintLabel();
		// }
		// labels.get(1).updateLabel();

		// Attempt at AI only GAME
		// int counter = 0;
		// while (counter < 100){
		// Thread thread4 = new Thread((Runnable)
		// gameMap.getPlayerList().get(0));
		// Thread thread5 = new Thread((Runnable)
		// gameMap.getPlayerList().get(1));
		// Thread thread6 = new Thread((Runnable)
		// gameMap.getPlayerList().get(2));
		// System.out.println("Bot Warfare Turn: " + (counter+1));
		// gameMap.getPlayerList().get(0).addBonus(3);
		// gameMap.getPlayerList().get(1).addBonus(3);
		// gameMap.getPlayerList().get(2).addBonus(3);
		//						
		// thread4.run();
		// thread5.run();
		// thread6.run();
		// counter++;
		// }
		// for (Continent temp : Map.continents){
		// for (Territory tempT : temp.listTerritory()){
		// tempT.addTroop(5);
		// }
		// }

	}

	private void broadcastMap() {
		replaceMapPlayer();
		oldMap = gameMap;
		((RiskFrame) getMyParent()).updateClientWithNewMap(gameMap);
	}

	private void endMyTurn() {
		replaceMapPlayer();
		broadcastMap();
		((RiskFrame) getMyParent()).endMyTurn(player);
	}

	private JFrame getMyParent() {
		return (JFrame) this.getParent().getParent().getParent().getParent();
	}

	public void updatePlayerTurn(PlayerTurn t) {
		System.out.println("Player Turn Updated " + t);
		player.setTurnPhase(t);
		updateButtons();
		validate();
	}

	private void replaceMapPlayer() {
		Iterator<Player> it = gameMap.getPlayerList().iterator();
		while (it.hasNext()) {
			Player temp = it.next();
			if (temp.getUUID().compareTo(playerID) == 0) {
				temp = player;
				break;
			}
		}
	}

	private Player getMapPlayer() {
		Iterator<Player> it = gameMap.getPlayerList().iterator();
		while (it.hasNext()) {
			Player temp = it.next();
			if (temp.getUUID().compareTo(playerID) == 0) {
				return temp;
			}
		}
		return null;
	}

	private void updateButtons() {
		// Display Correct Buttons Based On Players Turn State
		this.remove(actionPanel);
		actionPanel.removeAll();
		territoryOne = null;
		territoryTwo = null;

		turn = player.getTurnPhase();
		System.out.println("UpdateButtons - player turn = " + turn);
		if (turn == PlayerTurn.FALSE) {
			actionPanel.add(t1Panel);
			actionPanel.add(waitingButtons);
			actionPanel.add(t2Panel);
		} else if (turn == PlayerTurn.BONUS) {
//			if (player.getBonus() == 0) {
//				System.out.println("IS THIS EVER READ BONUS->ATTACK");
//				player.setTurnPhase(PlayerTurn.ATTACK);
//				turn = player.getTurnPhase();
//			} else {
				actionPanel.add(t1Panel);
				actionPanel.add(bonusButtons);
				actionPanel.add(t2Panel);
			
		}
		if (turn == PlayerTurn.CARDS) {
			MapInfo.calculateTurnBonus(player);
			actionPanel.add(t1Panel);
			actionPanel.add(cardButtons);
			actionPanel.add(t2Panel);
		} else if (turn == PlayerTurn.ATTACK) {
			actionPanel.add(t1Panel);
			actionPanel.add(attackButtons);
			actionPanel.add(t2Panel);
		} else if (turn == PlayerTurn.FORTIFY) {
			System.out.println("turn = Fortify");
			actionPanel.add(t1Panel);
			actionPanel.add(fortifyButtons);
			actionPanel.add(t2Panel);
		} else if (turn == PlayerTurn.START) {
			actionPanel.add(t1Panel);
			actionPanel.add(newGameButtons);
			actionPanel.add(t2Panel);
		}
		updatePanelLabels();
		add(actionPanel, BorderLayout.SOUTH);
	}

	public void updateMap(Map newMap) {

		// update the game Map
		oldMap = gameMap;
		gameMap = null;
		gameMap = newMap;

		if (gameMap == oldMap && oldMap != null) {
			System.out.println("This is the Map I just sent");
		} else {
			System.out.println("New Map");
			Iterator<Player> playerIt = gameMap.getPlayerList().iterator();
			while (playerIt.hasNext()) {
				Player temp = playerIt.next();
				if (temp.getUUID().compareTo(playerID) == 0) {
					player = temp;
					System.out.println("New Map player turn = "
							+ player.getTurnPhase());
					break;
				}
			}
		}

		// get last action
		if (gameMap.getLastAction() != null)
			System.out.println("Map Last Action: "
					+ gameMap.getLastAction().getLastActionEunm());

		// if(gameMap.getPhase() == GamePhase.PLAYING){
		// if(player.getTurnPhase() == PlayerTurn.START){
		// System.out.println("IS THIS EVER EVER CALLED???");
		// player.setTurnPhase(PlayerTurn.BONUS);
		// }
		// }
		// update the PlayerPanels
		// update available buttons based on players turn
		updateButtons();

		setPlayers();

		updateAllMarkers();

		validate();
	}

	private void updatePanelLabels() {
		if (territoryOne == null) {
			territory1.setText("No Territory Selected");
			t1Panel.setBackground(Color.WHITE);
		} else if (territoryOne.getRuler() instanceof NullPlayer) {
			t1Panel.setBackground(Color.WHITE);
		} else {
			t1Panel.setBackground(territoryOne.getRuler().getColor());
		}
		if (territoryTwo == null) {
			territory2.setText("No Territory Selected");
			t2Panel.setBackground(Color.WHITE);
		} else if (territoryTwo.getRuler() instanceof NullPlayer) {
			t2Panel.setBackground(Color.WHITE);
		} else {
			t2Panel.setBackground(territoryTwo.getRuler().getColor());
		}
		// validate();
	}

	private void updateMarker(Territory territoryUpdate) {
		for (int i = 0; i < labels.size(); i++) {
			if (labels.get(i).getTerritory() == territoryUpdate) {
				labels.get(i).paintLabel();
			}
		}
		updatePanelLabels(); // so panels reflect any change in territory color
	}

	private class TerritoryLabel {
		private Territory territory;
		private String str; // image location
		private int rgb;
		private int troops;

		public TerritoryLabel(Territory t) {
			territory = t;
			troops = territory.getTroopNumber();
			str = "images/numbers" + troops + ".png";
		}

		public Territory getTerritory() {
			return territory;
		}

		public void setTerritory(Territory t) {
			territory = t;
		}

		public String getNumString() {
			return str;
		}

		public int getRGB() {
			return rgb;
		}

		public int getTroops() {
			return territory.getTroopNumber();
		}

		public void paintLabel() {

			Graphics2D alpha = alphaMap.createGraphics();
			BufferedImage blankLabel = null;

			try {
				blankLabel = ImageIO.read(new File("images/alphaLabel.png"));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			BufferedImage label = null;
			Player territoryRuler = territory.getRuler();
			if (territoryRuler instanceof NullPlayer) {
				rgb = Color.WHITE.getRGB();
			} else {
				rgb = territoryRuler.getColor().getRGB();
			}

			try {

				label = ImageIO.read(new File("images/territoryLabel.png"));
				for (int x = 0; x < label.getWidth(); x++) {
					for (int y = 0; y < label.getHeight(); y++) {
						if (label.getRGB(x, y) != Color.WHITE.getRGB()) {
							if (label.getRGB(x, y) >>> 24 != blankLabel.getRGB(
									1, 1) >>> 24) {
								label.setRGB(x, y, rgb);
							} else {
								// System.out.println("alpha" + x + ", " + y);
							}
						}
					}
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			BufferedImage number = null;
			try {
				troops = territory.getTroopNumber();
				if (territory.getTroopNumber() <= 40
						&& territory.getTroopNumber() >= 0) {
					str = "images/numbers/" + troops + ".png";
					number = ImageIO.read(new File(str));
				} else
					number = ImageIO
							.read(new File("images/numbers/tooMany.png"));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Point p = territory.getPoint();
			alpha.drawImage(blankLabel, p.x, p.y, map); // erase previous label
			alpha.drawImage(label, p.x, p.y, map); // draw new label
			alpha.drawImage(number, p.x, p.y, map); // draw num troops over
			// circle

			// return alphaMap;
		}

		public void updateLabel() {
			paintLabel();
			Graphics2D g = mapImageG.createGraphics();
			g.drawImage(alphaMap, 0, 0, null);
			map.setIcon(new ImageIcon(mapImageG));
		}
	}

	// TODO When Cam adds in the ActionListener for the controls that will
	// create a
	// new Movement, also add in a call to 'RiskClient.unlock()'

	/**
	 * 
	 */
	private class startAttackListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (territoryOne != null && territoryOne != territoryTwo
					&& territoryTwo != null) {
				if (playerID.compareTo(territoryOne.getRuler().getUUID()) == 0) {
					if (territoryOne.getTroopNumber() <= 1) {
						System.out.println("Can't Attack With 1 Troop");
					} else if (territoryOne.getRuler().getUUID().compareTo(
							territoryTwo.getRuler().getUUID()) != 0) {
						if (territoryOne.listNeighbors().contains(territoryTwo)) {
							Combat c = new Combat(territoryOne, territoryTwo);
							System.out.println("Combat Made");
							 new AudioPlay("audio/gunShot_Ping.wav").start();
							 new Animate("images/explodeSprite", 1, 100);
							updateMarker(territoryOne);
							updateMarker(territoryTwo);
							new AttackFrame(c);
							if (player.isCardEligible()) {
								if (territoryTwo.getRuler() == territoryOne
										.getRuler()) {
									popUpTroopConquer(territoryOne,
											territoryTwo);
								}
							} else {
								broadcastMap();
							}

						}
					} else {
						System.out.println("Same Owner");
					}

				} else {
					System.out.println("T1 Owner Issues");
				}
			}
		}
	}

	/**
	 *
	 */
	private class endAttackListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (player.isCardEligible()) {
				gameMap.giveCard(player);
				int size = player.getCards().size();
				Card card = player.getCards().get(size - 1);
				player.setCardEligible(false);
				ImageIcon image = new ImageIcon("images/cards/"
						+ card.getType().toString() + ".png");
				JOptionPane.showMessageDialog(null,
						"You Got a Card! That a-way slugger!\n"
								+ card.getTerritory().getTerritoryName(),
						"Card Received", 1, image);
			}
			updatePlayerTurn(PlayerTurn.FORTIFY);
		}
	}

	private void updateAllMarkers() {
		int i = 0;

		Iterator<Territory> it = gameMap.allTerritories().iterator();
		while (it.hasNext()) {
			Territory temp = it.next();
			if (labels.get(i) == null) {
				System.out.println("NULL LABEL FOUND - BREAK");
				break;
			}
			if (labels.get(i).getTerritory().getRuler().getUUID().compareTo(
					temp.getRuler().getUUID()) == 0) {
				if (labels.get(i).getTroops() == temp.getTroopNumber()) {
					i++;
				} else {
					System.out.println("Update label same ruler diff troop# ");
					labels.get(i).setTerritory(temp);
					labels.get(i).paintLabel();
					i++;
				}
			} else {
				System.out.println("NEW LABEL------------------------");
				labels.get(i).setTerritory(temp);
				labels.get(i).paintLabel();
				i++;
			}
		}

		Graphics2D g = mapImageG.createGraphics();
		g.drawImage(alphaMap, 0, 0, null);
		map.setIcon(new ImageIcon(mapImageG));

		// for (i = 0; i < labels.size() - 1; i++) {
		// TerritoryLabel temp = labels.get(i);
		// String str = temp.getNumString();
		// if(temp.getTerritory().getRuler() instanceof NullPlayer){
		//				
		// }
		// else if (str.compareTo("images/numbers/"
		// + temp.getTerritory().getTroopNumber() + ".png") != 0) {
		// temp.paintLabel();
		// }
		// else if (temp.getTerritory().getRuler().getColor().getRGB() != temp
		// .getRGB()) {
		// temp.paintLabel();
		// }
		// labels.get(i).updateLabel();
	}

	/**
	 * 
	 */
	private void setPlayers() {

		this.remove(gridRightPlayers);
		this.remove(gridLeftPlayers);
		// gridLeftPlayers.removeAll();
		// gridRightPlayers.removeAll(); ?? needed???

		gridLeftPlayers = new JPanel();
		gridLeftPlayers.setLayout(new GridLayout(3, 1));

		gridRightPlayers = new JPanel();
		gridRightPlayers.setLayout(new GridLayout(3, 1));
		int i;
		for (i = 0; i < gameMap.getPlayerList().size() / 2; i++) {
			gridLeftPlayers.add(new PlayerPanel(gameMap.getPlayerList().get(i),
					playerID));
		}
		for (i = i; i < gameMap.getPlayerList().size(); i++) {
			gridRightPlayers.add(new PlayerPanel(
					gameMap.getPlayerList().get(i), playerID));
		}

		this.add(gridLeftPlayers, BorderLayout.WEST);

		if (gridRightPlayers.getComponentCount() > 0)
			this.add(gridRightPlayers, BorderLayout.EAST);
		else {
			gridRightPlayers.add(new JLabel(new ImageIcon(
					"images/player/Wall-E.png")));
			this.add(gridRightPlayers);
		}
		// validate();
	}

	 private void updatePlayers(){
	
		 JPanel tempLeft = new JPanel();
		 JPanel tempRight = new JPanel();
		 
		 int i;
		for (i = 0; i < gameMap.getPlayerList().size() / 2; i++) {
			tempLeft.add(new PlayerPanel(gameMap.getPlayerList().get(i),
				playerID));
		}
		for (i = i; i < gameMap.getPlayerList().size(); i++) {
			tempRight.add(new PlayerPanel(
					gameMap.getPlayerList().get(i), playerID));
		}
		
		// new panels built, exhange old for new;
		
		gridLeftPlayers = tempLeft;
		gridRightPlayers = tempRight;
		
	 }
	private boolean emptyTerritoryExists() {
		Iterator<Territory> it = gameMap.allTerritories().iterator();
		while (it.hasNext()) {
			if (it.next().getRuler() instanceof NullPlayer) {
				return true;
			}
		}
		gameMap.setPhase(GamePhase.PLACING);
		return false;
	}

	private boolean bonusTroopsExist() {

		Iterator<Player> it = gameMap.getPlayerList().iterator();
		while (it.hasNext()) {
			if (it.next().getBonus() != 0) {
				return true;
			}
		}
		gameMap.setPhase(GamePhase.PLAYING);
		return false;
	}

	// private class EndAddOneListener implements ActionListener {
	//
	// @Override
	// public void actionPerformed(ActionEvent e) {
	// player.setTurnPhase(PlayerTurn.BONUS);
	// updateButtons();
	// validate();
	//			
	// }
	// }

	private class AddOneListener implements ActionListener {
		public void actionPerformed(ActionEvent arg0) {
			if (territoryOne != null) {
				if (territoryOne.getRuler() instanceof NullPlayer
						|| !emptyTerritoryExists()) {
					if (bonusTroopsExist()) {
						if (player.getBonus() > 0) {
							if (territoryOne.getTroopNumber() == 0) {
								territoryOne.setRuler(player);
							}
							territoryOne.addTroop(1);
							player.removeBonus(1);
							updateMarker(territoryOne);
							updatePlayerTurn(PlayerTurn.FALSE);
							// setPlayers();
							gameMap.setLastAction(new LastAction(player,
									territoryOne, LastActionEnum.addTroops));
							broadcastMap();
							endMyTurn();
						} else
							JOptionPane.showMessageDialog(null,
									"Must Have Bonus Troops To Add");
					} else {
						JOptionPane.showMessageDialog(null,
								"No Bonus Troops In Map - Advance To Playing");
						updatePlayerTurn(PlayerTurn.CARDS);
					}
				} else
					JOptionPane.showMessageDialog(null,
							"Must Select Un-Occupied Territory");
			} else
				JOptionPane.showMessageDialog(null, "Must Select Territory 1");
		}
	}

	/**
	 * 
	 * @author cadamson
	 * 
	 */
	private class AddTroopsListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (territoryOne == null) {
				JOptionPane.showMessageDialog(null, "Must Select Territory 1");
				return;
			}
			if (territoryOne.getRuler().getUUID().compareTo(playerID) != 0) {
				JOptionPane.showMessageDialog(null, "Can't Add Troops: "
						+ territoryOne.getTerritoryName()
						+ " Is Not Yours \nVery Thoughfull Though");
				return;
			}
			popUpTroopAdd(territoryOne);
		}
	}

	private class EndAddListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			updatePlayerTurn(PlayerTurn.CARDS);
			return;
		}
	}

	private class TradeCardsListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			// JOptionPane.showMessageDialog(null, "Trade Cards Here");
			// if(player.getCards().size() > 0) {
			new TradeCardsFrame(player);
			return;
		}
	}

	private class EndTradeListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			updatePlayerTurn(PlayerTurn.ATTACK);
			broadcastMap();
			return;
		}
	}

	private class FortifyListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (territoryOne != null) {
				if (territoryTwo != null) {
					if (player == territoryOne.getRuler()) {
						if (player == territoryTwo.getRuler()) {
							if (territoryOne.listNeighbors().contains(
									territoryTwo)) {
								popUpTroopFortify(territoryOne, territoryTwo);
								return;
							}
						}
					}
				}
			}
		}
	}

	private class EndTurnListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			updatePlayerTurn(PlayerTurn.FALSE);
			endMyTurn();
			return;
		}
	}

	/**
	 * 
	 * @param t
	 */
	private void popUpTroopFortify(Territory one, Territory two) {
		if (one.getTroopNumber() <= 0) {
			JOptionPane.showMessageDialog(null, "No Troops to Move from T1");
			return;
		}
		Object[] possibilities = new Object[one.getTroopNumber()];
		for (int i = 0; i < one.getTroopNumber(); i++) {
			possibilities[i] = i;
		}
		Object n = JOptionPane.showInputDialog(null, "Troops to move from "
				+ one.getTerritoryName() + " to " + two.getTerritoryName()
				+ "?", "Number of Troops to Add", JOptionPane.PLAIN_MESSAGE,
				null, possibilities, possibilities[0]);
		if (n != null) {
			if (n instanceof Integer) {
				int num = (Integer) n;
				two.addTroop(num);
				one.removeTroop(num);
				updateMarker(one);
				updateMarker(two);
				// validate();
				broadcastMap();
			}
		}
	}

	private void popUpTroopConquer(Territory one, Territory two) {
		if (one.getTroopNumber() <= 0) {
			JOptionPane.showMessageDialog(null, "No Troops to Move from T1");
			return;
		}

		Object[] possibilities;
		if (one.getTroopNumber() - 1 >= 3) {
			int minAdd = 3;
			possibilities = new Object[one.getTroopNumber() - (minAdd)];
			for (int i = 0; i < possibilities.length; i++) {
				possibilities[i] = i + minAdd;
			}
		} else if (one.getTroopNumber() - 1 == 2) {
			possibilities = new Object[1];
			possibilities[0] = 2;
		} else {
			possibilities = new Object[1];
			possibilities[0] = 1;
		}
		Object n = JOptionPane.showInputDialog(null, "Troops to move from "
				+ one.getTerritoryName() + " to " + two.getTerritoryName()
				+ "?", "You Conquered a Territory!!!",
				JOptionPane.PLAIN_MESSAGE, new ImageIcon(
						"images/Party_machine.gif"), possibilities,
				possibilities[0]);
		if (n != null) {
			if (n instanceof Integer) {
				int num = (Integer) n;
				two.addTroop(num);
				one.removeTroop(num);
				updateMarker(one);
				updateMarker(two);
				validate();
				broadcastMap();
			}
		}
	}

	/**
	 * 
	 * @param t
	 */
	private void popUpTroopAdd(Territory t) {
		Object[] possibilities = new Object[player.getBonus() + 1];
		for (int i = 0; i < player.getBonus() + 1; i++) {
			possibilities[i] = i;
		}
		Object n = JOptionPane.showInputDialog(null, "Troops to move to "
				+ t.getTerritoryName() + "?", "Number of Troops to Add",
				JOptionPane.PLAIN_MESSAGE, null, possibilities,
				possibilities[0]);
		if (n != null) {
			if (n instanceof Integer) {
				int num = (Integer) n;
				t.addTroop(num);
				player.removeBonus(num);
				// updateMarker(territoryOne);
				// gridLeftPlayers.removeAll();
				// gridRightPlayers.removeAll();
				// setPlayers();
				// validate();
				broadcastMap();
			}
		}
	}

	/**
	 * 
	 */
	private class MouseClickEvent implements MouseListener {
		private BufferedImage image;

		public MouseClickEvent(BufferedImage img) {
			this.image = img;
		}

		@Override
		public void mouseClicked(MouseEvent arg0) {
			Point clickPoint = arg0.getPoint();
			int x = clickPoint.x;
			int y = clickPoint.y - 5;
			int RGB = image.getRGB(x, y);
			Territory territory = gameMap.getTerritory(RGB);
			if (territory != null) {
				// if(territory.getRuler() instanceof NullPlayer){
				// return;
				// }
				//System.out.print(territory.getRuler().getName()+" "+territory.
				// getTroopNumber
				// ()+" "+territory.getTerritoryName()+" "+territory
				// .listNeighbors().toString()+"\n");

				if (arg0.getButton() == MouseEvent.BUTTON1) {
					if (territory.getRuler() instanceof NullPlayer) {
						territory1.setText("Territory 1: "
								+ territory.getTerritoryName());
						territory1.setBackground(Color.WHITE);
						territoryOne = territory;
					} else if (territory.getRuler() != player) {
						return;
					} else {
						territory1.setText("Territory 1: "
								+ territory.getTerritoryName());
						territory1.setBackground(territory.getRuler()
								.getColor());
						territoryOne = territory;
					}
				} else if (arg0.getButton() == MouseEvent.BUTTON3) {
					if (territory.getRuler() instanceof NullPlayer) {
						return;
					}
					territory2.setText("Territory 2: "
							+ territory.getTerritoryName());
					territory2.setBackground(territory.getRuler().getColor());
					territoryTwo = territory;
				}
				topPanel.setText("              "
						+ territory.getTerritoryName()
						+ "       neighbors are - "
						+ territory.listNeighbors().toString());
				updatePanelLabels();
				// validate();
			} else {
				if (arg0.getButton() == MouseEvent.BUTTON1) {
					territoryOne = null;
				} else if (arg0.getButton() == MouseEvent.BUTTON3) {
					territoryTwo = null;
				}
				updatePanelLabels();
				// validate();
			}
		}

		public void mouseEntered(MouseEvent arg0) {
		}

		public void mouseExited(MouseEvent arg0) {
		}

		public void mousePressed(MouseEvent e) {
		}

		public void mouseReleased(MouseEvent e) {
		}
	}
}
